// Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CLOUDAPPENGINE_CAECONTROLCMDHANDLETHREAD_H
#define CLOUDAPPENGINE_CAECONTROLCMDHANDLETHREAD_H

#include <map>
#include <functional>
#include "../cae_dataPipe/CaeDataPipe.h"
#include "../cae_common/CaeAesUtils.h"
#include "../cae_service/CaeParamStorage.h"
#include "../cae_common/CaeAppCtrlCmdUtils.h"

using VerifyRetCallback = std::function<void (bool success, bool secondVerify,
        const std::string& connectionId, const std::string& ClientPlatformType)>;
using ActionCallback = std::function<void (std::string& connectionId, COMMAND_TYPE commandType)>;

class CaeSocketAgent;
class CaeControlCmdHandleThread : public CaeThread {
public:
    explicit CaeControlCmdHandleThread(const std::weak_ptr<CaeSocketAgent>& socketAgent);

    ~CaeControlCmdHandleThread() override;

    const std::shared_ptr<CaeParamStorage> &GetParamStorage() const;

    void SetParamStorage(std::shared_ptr<CaeParamStorage> &paramStorage);

    void Run() override;

    void SetVerifyCallback(const VerifyRetCallback &callback);

    void SetActionCallback(const ActionCallback &callback);

private:

    void HandleStartCmd(std::map<std::string, std::string> &parameters);

    bool CheckAndStoreParams(std::map<std::string, std::string> &parameters);

    int QueryAesKeyAndVerifyData(std::map<std::string, std::string> &parameters);

    bool UpdateCertFile();

    int VerifySignatureWithPublicKeyCrt(std::string phoneId);

    std::string QueryAesKeyWithSignCheckUrl();

    bool ParseStartInfo(std::string &encryptData, AesInfo *aesInfo);

    void HandleSetMediaConfigCmd(std::map<std::string, std::string> &parameters);

    void HandleStopCmd(std::map<std::string, std::string> &parameters);

    void HandlePauseCmd(std::map<std::string, std::string> &parameters);

    void HandleReconnectCmd(std::map<std::string, std::string> &parameters);

    void HandleResumeCmd(std::map<std::string, std::string> &parameters);

    char* ParseMediaConfig(std::string mediaConfig);

    bool Init();

    void Deinit() noexcept;

    void HandleCommand(int commandType, std::map<std::string, std::string> parameters);

private:
    AesInfo *m_aesInfo = nullptr;
    std::shared_ptr<CaeParamStorage> m_paramStorage = nullptr;
    std::weak_ptr<CaeSocketAgent> m_socketAgent;

    VerifyRetCallback m_verifyRetCallback = nullptr;
    ActionCallback m_actionCallback = nullptr;
};

#endif // CLOUDAPPENGINE_CAECONTROLCMDHANDLETHREAD_H
